#include "adc.h"
#include "gpio.h"
#include "dmac.h"
#include "bgr.h"
#include "hal_adc.h"
#include "hc32l13x.h"
#include "interrupt.h"

/*
 *　adc_data[0] --> UBUS
 *　adc_data[1] --> Valve Current
 *　adc_data[2] --> Heater Current
 *　adc_data[3] --> K15 signal
 *　adc_data[4] --> Mode button
 *　adc_data[5] --> Driver button
 *　adc_data[6] --> Environment temperature
 */
volatile unsigned short adc_data[7] = {0, 0, 0, 0, 0, 0, 0};

/* ADC io pins config */
static void adc_gpio_config(void)
{
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
    Gpio_SetAnalogMode(UBUS_PORT, UBUS_PIN);
    Gpio_SetAnalogMode(VALVE_CURRENT_PORT, VALVE_CURRENT_PIN);
    Gpio_SetAnalogMode(HEATER_CURRENT_PORT, HEATER_CURRENT_PIN);
    Gpio_SetAnalogMode(KEY_SIGNAL_PORT, KEY_SIGNAL_PIN);
    Gpio_SetAnalogMode(MODE_BUTTON_PORT, MODE_BUTTON_PIN);
    Gpio_SetAnalogMode(DERIVER_BUTTON_PORT, DERIVER_BUTTON_PIN);
    Gpio_SetAnalogMode(TEMPERATURE_PORT, TEMPERATURE_PIN);
}

static void adc_config(void)
{
    stc_adc_cfg_t adc_config_struct;
    DDL_ZERO_STRUCT(adc_config_struct);
	
    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE); // 打开ADC和BGR时钟
    Bgr_BgrEnable();                                          // 开启 BGR 
	
    adc_config_struct.enAdcMode         = AdcScanMode;         // 扫描模式
    adc_config_struct.enAdcClkDiv       = AdcMskClkDiv1;       // 时钟分频
    adc_config_struct.enAdcSampCycleSel = AdcMskSampCycle8Clk; // 采样周期数
    adc_config_struct.enAdcRefVolSel    = AdcMskRefVolSelAVDD; // 参考电压选择
    adc_config_struct.enAdcOpBuf        = AdcMskBufDisable;    // 不放大
    adc_config_struct.enInRef           = AdcMskInRefDisable;  // 内部参考电压禁止
    adc_config_struct.enAdcAlign        = AdcAlignRight;       // 转换结果右对齐
    Adc_Init(&adc_config_struct);
}

static void adc_sqr_config(void)
{
    stc_adc_sqr_cfg_t adc_sqr_config_structure;
    DDL_ZERO_STRUCT(adc_sqr_config_structure);

    adc_sqr_config_structure.bSqrDmaTrig = FALSE;              // ADC转换完成触发DMA
    adc_sqr_config_structure.enResultAcc = AdcResultAccEnable; // 转换结果不累加
    adc_sqr_config_structure.u8SqrCnt    = 8;                  // 规则组长度
    Adc_SqrModeCfg(&adc_sqr_config_structure);

	/* 配置转换通道 */
    Adc_CfgSqrChannel(AdcSQRCH0MUX, AdcExInputCH0);
    Adc_CfgSqrChannel(AdcSQRCH1MUX, AdcExInputCH1);
    Adc_CfgSqrChannel(AdcSQRCH2MUX, AdcExInputCH2);
    Adc_CfgSqrChannel(AdcSQRCH3MUX, AdcExInputCH3);
    Adc_CfgSqrChannel(AdcSQRCH4MUX, AdcExInputCH4);
    Adc_CfgSqrChannel(AdcSQRCH5MUX, AdcExInputCH5);
    Adc_CfgSqrChannel(AdcSQRCH6MUX, AdcExInputCH6);
}

static void adc_dma_config(void)
{
    stc_dma_cfg_t dma_config_structure;
	DDL_ZERO_STRUCT(dma_config_structure);
	
    Sysctrl_SetPeripheralGate(SysctrlPeripheralDma, TRUE); // 打开DMA时钟
    
    dma_config_structure.enMode              = DmaMskBlock;                // 选择块传输
    dma_config_structure.u16BlockSize        = 0x07;                       // 块传输个数
    dma_config_structure.u16TransferCnt      = 7;                          // 块传输次数，一次传输数据大小为 块传输个数*BUFFER_SIZE
    dma_config_structure.enTransferWidth     = DmaMsk16Bit;                // 传输数据的宽度
    dma_config_structure.enSrcAddrMode       = DmaMskSrcAddrInc;           // 源地址自增
    dma_config_structure.enDstAddrMode       = DmaMskDstAddrInc;           // 目的地址自增
    dma_config_structure.enDestAddrReloadCtl = DmaMskDstAddrReloadDisable; // 禁止重新加载传输目的地址
    dma_config_structure.enSrcAddrReloadCtl  = DmaMskSrcAddrReloadDisable; // 禁止重新加载传输源地址
    dma_config_structure.enSrcBcTcReloadCtl  = DmaMskBcTcReloadEnable;     // 使能重新加载BC/TC值

    dma_config_structure.u32SrcAddress  = (uint32_t)M0P_ADC->SQRRESULT0; // 指定传输源地址
    dma_config_structure.u32DstAddress  = (uint32_t)&adc_data[0];        // 指定传输目的地址
    dma_config_structure.enRequestNum   = DmaADCSQRTrig;                 // 设置为软件触发
    dma_config_structure.enTransferMode = DmaMskContinuousTransfer;      // 连续转换
    dma_config_structure.enPriority     = DmaMskPriorityFix;             // 各通道固定优先级，CH0优先级 > CH1优先级
    Dma_InitChannel(DmaCh0, &dma_config_structure);

    //Dma_EnableChannelIrq(DmaCh1);           // 传输成功完成时产生中断
    //EnableNvic(DMAC_IRQn, IrqLevel3, TRUE); // NVIC对应DMAC中断位使能

    Dma_Enable();              // 使能DMA
    Dma_EnableChannel(DmaCh0); // 使能DmaCh0
    Dma_SwStart(DmaCh0);
}

void hal_adc_init(void)
{
    adc_gpio_config();
    adc_config();
    adc_sqr_config();
    //adc_dma_config();
    
    Adc_EnableIrq();
    EnableNvic(ADC_IRQn, IrqLevel3, TRUE);
}


/* 将ADC数据转换为电压 */
float convert_data_to_voltage(unsigned short data)
{
	float tmp = (((float)data)*5)/4095;
	return tmp;
}

